/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /**
 * @addtogroup AVRecorder
 * @{
 *
 * @brief 提供请求录制能力的API。
 *
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @since 16
 * @}
 */

 /**
 * @file avrecorder.h
 *
 * @brief 定义AVRecorder接口。应用可使用Media AVRecorder提供的接口录制媒体数据。
 *
 * @kit MediaKit
 * @library libavrecorder.so
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @include <multimedia/player_framework/avrecorder.h>
 * @since 16
 */

#ifndef MULTIMEDIA_PLAYER_FRAMEWORK_NATIVE_AVRECORDER_H
#define MULTIMEDIA_PLAYER_FRAMEWORK_NATIVE_AVRECORDER_H

#include <memory>
#include <stdint.h>
#include <stdio.h>
#include "avrecorder_base.h"
#include "native_averrors.h"
#include "native_window/external_window.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 创建AVRecorder实例。调用成功之后进入AVRECORDER_IDLE状态。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @return 成功时返回指向 OH_AVRecorder 实例的指针，失败时返回 nullptr。
 * @since 16
*/
OH_AVRecorder *OH_AVRecorder_Create(void);

/**
 * @brief 配置AVRecorder参数，准备录制。必须在{@link OH_AVRecorder_Start}成功触发之后调用，调用成功之后进入AVRECORDER_PREPARED状态。
 *
 * 若只录制音频，则无需配置视频相关参数；同理，若只录制视频，则无需配置音频相关参数。
 *
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param config 指向 OH_AVRecorder_Config 实例的指针，见 {@link OH_AVRecorder_Config}。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或者准备失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_Prepare(OH_AVRecorder *recorder, OH_AVRecorder_Config *config);

/**
 * @brief 获取当前的录制参数。此接口必须在录制准备完成后调用。传入的 *config 必须为 nullptr，由框架层统一分配和释放内存，以避免内存管理混乱，防止内存泄漏或重复释放等问题。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param config 指向 OH_AVRecorder_Config 实例的指针，见 {@link OH_AVRecorder_Config}。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或 *config 不为 nullptr；\n
 *         {@link AV_ERR_NO_MEMORY} 如果内存不足，*config 内存分配失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_GetAVRecorderConfig(OH_AVRecorder *recorder, OH_AVRecorder_Config **config);

/**
 * @brief 获取输入Surface。必须在{@link OH_AVRecorder_Prepare}成功触发之后，{@link OH_AVRecorder_Start}之前调用。
 *
 * 此Surface提供给调用者，调用者从此Surface中获取Surface Buffer，填入相应的视频数据。
 *
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param window 指向 OHNativeWindow 实例的指针，见 {@link OHNativeWindow}。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_GetInputSurface(OH_AVRecorder *recorder, OHNativeWindow **window);

/**
 * @brief 更新视频旋转角度。必须在{@link OH_AVRecorder_Prepare}成功触发之后，{@link OH_AVRecorder_Start}之前调用。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param rotation 视频旋转角度，必须是整数 [0, 90, 180, 270] 中的一个。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或输入的 rotation 不符合要求或更新方向失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_UpdateRotation(OH_AVRecorder *recorder, int32_t rotation);

/**
 * @brief 开始录制。必须在{@link OH_AVRecorder_Prepare}成功触发之后调用，调用成功之后进入AVRECORDER_STARTED状态。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或启动失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_Start(OH_AVRecorder *recorder);

/**
 * @brief 暂停录制。必须在{@link OH_AVRecorder_Start}成功触发之后，处于AVRECORDER_STARTED状态时调用，调用成功之后进入AVRECORDER_PAUSED状态。
 *
 * 之后可以通过调用{@link OH_AVRecorder_Resume}恢复录制，重新进入AVRECORDER_STARTED状态。
 *
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或暂停失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_Pause(OH_AVRecorder *recorder);

/**
 * @brief 恢复录制。必须在{@link OH_AVRecorder_Pause}成功触发之后，处于PAUSED状态时调用，调用成功之后重新进入AVRECORDER_STARTED状态。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或恢复失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_Resume(OH_AVRecorder *recorder);

/**
 * @brief 停止录制。必须在{@link OH_AVRecorder_Start}成功触发之后调用，调用成功之后进入AVRECORDER_STOPPED状态。
 *
 * 纯音频录制时，需要重新调用{@link OH_AVRecorder_Prepare}接口才能重新录制。
 * 纯视频录制、音视频录制时，需要重新调用{@link OH_AVRecorder_Prepare}和{@link OH_AVRecorder_GetInputSurface}接口才能重新录制。
 *
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或停止失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_Stop(OH_AVRecorder *recorder);

/**
 * @brief 重置录制状态。必须在非AVRECORDER_RELEASED状态下调用，调用成功之后进入AVRECORDER_IDLE状态。
 *
 * 纯音频录制时，需要重新调用{@link OH_AVRecorder_Prepare}接口才能重新录制。
 * 纯视频录制、音视频录制时，需要重新调用{@link OH_AVRecorder_Prepare}和{@link OH_AVRecorder_GetInputSurface}接口才能重新录制。
 *
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或重置失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_Reset(OH_AVRecorder *recorder);

/**
 * @brief 释放录制资源。调用成功之后进入AVRECORDER_RELEASED状态。调用此接口释放录制资源后，recorder 内存将释放，应用层需要显式地将 recorder 指针置空，避免访问野指针。
 *
 * 调用此接口释放录制资源后，recorder 内存将释放，应用层需要显式地将 recorder 指针置空，避免访问野指针。
 * 释放音视频录制资源之后，该 OH_AVRecorder 实例不能再进行任何操作。
 *
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或释放失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_Release(OH_AVRecorder *recorder);

/**
 * @brief 获取 AVRecorder 可用的编码器和编码器信息。参数 *info 必须为 nullptr，由框架层统一分配和释放内存，以避免内存管理混乱，防止内存泄漏或重复释放等问题。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param info 指向 OH_AVRecorder_EncoderInfo 实例的指针，见 {@link OH_AVRecorder_EncoderInfo}。
 * @param length 可用编码器的长度。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr；\n
 *         {@link AV_ERR_NO_MEMORY} 如果内存不足，*info 内存分配失败。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_GetAvailableEncoder(OH_AVRecorder *recorder, OH_AVRecorder_EncoderInfo **info,
    int32_t *length);

/**
 * @brief 设置状态回调函数，以便应用能够响应AVRecorder生成的状态变化事件。此接口必须在{@link OH_AVRecorder_Start}调用之前调用。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param callback 状态回调函数，见 {@link OH_AVRecorder_OnStateChange}。
 * @param userData 指向用户特定数据的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或回调函数为 nullptr。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_SetStateCallback(
    OH_AVRecorder *recorder, OH_AVRecorder_OnStateChange callback, void *userData);

/**
 * @brief 设置错误回调函数，以便应用能够响应AVRecorder生成的错误事件。此接口必须在{@link OH_AVRecorder_Start}调用之前调用。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param callback 错误回调函数，见 {@link OH_AVRecorder_OnError}。
 * @param userData 指向用户特定数据的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或回调函数为 nullptr。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_SetErrorCallback(OH_AVRecorder *recorder, OH_AVRecorder_OnError callback, void *userData);

/**
 * @brief 设置 URI 回调函数，以便应用能够响应AVRecorder生成的 URI 事件。此接口必须在 {@link OH_AVRecorder_Start} 调用之前调用。
 * @syscap SystemCapability.Multimedia.Media.AVRecorder
 * @param recorder 指向 OH_AVRecorder 实例的指针。
 * @param callback URI 回调函数，见 {@link OH_AVRecorder_OnUri}。
 * @param userData 指向用户特定数据的指针。
 * @return 函数结果代码：
 *         {@link AV_ERR_OK} 如果执行成功；\n
 *         {@link AV_ERR_INVALID_VAL} 如果输入的 recorder 为 nullptr 或回调函数为 nullptr。
 * @since 16
 */
OH_AVErrCode OH_AVRecorder_SetUriCallback(OH_AVRecorder *recorder, OH_AVRecorder_OnUri callback, void *userData);

#ifdef __cplusplus
}
#endif

#endif // MULTIMEDIA_PLAYER_FRAMEWORK_NATIVE_AVRECORDER_H
